package com.tarena.lbs.basic.web.service.impl;

import com.alibaba.nacos.api.utils.StringUtils;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.basic.web.dao.repository.AdminRepository;
import com.tarena.lbs.basic.web.dao.repository.UserRespository;
import com.tarena.lbs.basic.web.service.LoginService;
import com.tarena.lbs.common.passport.encoder.JwtEncoder;
import com.tarena.lbs.common.passport.enums.Roles;
import com.tarena.lbs.common.passport.principle.UserPrinciple;
import com.tarena.lbs.pojo.basic.bo.AdminBO;
import com.tarena.lbs.pojo.basic.bo.LoginBO;
import com.tarena.lbs.pojo.basic.bo.UserBO;
import com.tarena.lbs.pojo.passport.param.AdminLoginParam;
import com.tarena.lbs.pojo.passport.param.UserLoginParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private AdminRepository adminRepository;
    @Autowired
    private JwtEncoder<UserPrinciple> jwtEncoder;
    @Autowired
    private UserRespository userRespository;

    @Override
    public AdminBO adminDoLogin(AdminLoginParam param) throws BusinessException {
        log.debug("用户登录模块入参 param:{}",param);
        //1.根据Phone属性,查询user信息
        String phone = param.getPhone();
        AdminBO adminBO = adminRepository.getUserByPhone(phone);
        log.debug("根据手机号查询用户信息,出参adminBO:{}",adminBO);
        //2.效验是否存在数据库
        if (adminBO==null || adminBO.getId()==null){
            throw new BusinessException("100","用户不存在");
        }
        //3.存在,效验密码是否相等
        matchPassword(param.getPassword(),adminBO.getAccountPassword());
        log.debug("用户登录模块效验密码成功");
        //4.如果效验成功,生成JWT 封装查询adminBO返回
        generateJwt(adminBO);
        return adminBO;
    }

    @Override
    public UserBO userDoLogin(UserLoginParam param) throws BusinessException {
        //1.根据Phone电话号,判断是否存在此用户
        UserBO userBO=userRespository.getUserByPhone(param.getPhone());
        //2.判断是否存在
        if(userBO == null || userBO.getId() == null){
            throw new BusinessException("100","用户不存在");
        }
        //3.存在则对比密码
        matchPassword(param.getPassword(),userBO.getPassword());
        //4.生成JWT
        generateJwt(userBO);
        return userBO;
    }

    //多态的应用
    private void generateJwt(LoginBO loginBO) throws BusinessException{
        //1.准备好一个写入Jwt的数据对像userPrinciple 利用adminBO 封装
        UserPrinciple userPrinciple = new UserPrinciple();
        userPrinciple.setId(loginBO.getId());
        userPrinciple.setNickname(loginBO.getNickname());
        //2.根据adminBO中的属性accountTyp 给角色权限
        Integer roleNum = loginBO.getRoles();
        Roles role = null;
        switch (roleNum) {
            case 0:
                role = Roles.ADMIN;
                break;
            case 1:
                role = Roles.SHOP;
                break;
            default:
                role = Roles.USER;
        }
        userPrinciple.setRole(role);
        //3.生成JWT
        String jwt = jwtEncoder.generateToken(userPrinciple);
        //4.封装JWT
        loginBO.setJwt(jwt);
    }

    //生成JWT
    private void generateJwt(AdminBO adminBO) throws BusinessException {
        log.debug("生成JWT入参 AdminBO={}",adminBO);
        //1.准备好一个写入Jwt的数据对像userPrinciple 利用adminBO 封装
        UserPrinciple userPrinciple = new UserPrinciple();
        userPrinciple.setId(adminBO.getId());
        userPrinciple.setNickname(adminBO.getNickname());
        //2.根据adminBD中accountType的值给他赋值
        userPrinciple.setRole(adminBO.getAccountType()==0? Roles.ADMIN : Roles.SHOP);
        //3.生成JWT使用jwtEncoder
        String jwt = jwtEncoder.generateToken(userPrinciple);
        log.debug("生成的JWT:{}",jwt);
        //4. adminBD 缺少jwt字段
        adminBO.setJwt(jwt);
    }

    //效验密码是否相等
    private void matchPassword(String password, String accountPassword) throws BusinessException {
        log.debug("效验密码是否相等入参: password{},accountPassword:{}",password,accountPassword);
        boolean equals = StringUtils.equals(password, accountPassword);
        //只要不相同,就抛出异常
        if (!equals){
            throw  new BusinessException("101","密码错误");
        }
    }
}
